home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / misc / Life.lzh / Life / src / life68.asm < prev    next >
Assembly Source File  |  1993-03-13  |  6KB  |  259 lines

  1. ;
  2. ;   Life in 68000!
  3. ;
  4.     public    _dogen
  5. ;
  6. ;   This is the world's fastest life code, written for the 68000.
  7. ;   (Actually, I've discovered an even faster algorithm, but the
  8. ;   margin is too small to contain it.)
  9. ;
  10. ;   Input is:
  11. ;
  12. ; 60   long *s ; // old life generation we compute new one from
  13. ; 64   long *d ; // where to put the result; must also be generation before s
  14. ;                //    if not generation before s, set `m' array to all 1's.
  15. ; 68   short w ; // the width of the input array in *bytes*; must be divisible
  16. ;                //    by 4 and <= 128; this is the width to do *now*.
  17. ; 70   short h ; // the height of the input array in pixels; no constraints.
  18. ; 72   long *m ; // an array that indicates what's changing on the screen.
  19. ;                //    must be `h+1' longwords long, and the actual `m' pointer
  20. ;                //    passed has to point to the second longword.  The first
  21. ;                //    longword (actually *(m-1)) should always be 0.
  22. ; 76   long *t ; // a temporary array we use internally; must be 6 * w bytes
  23. ;                //    long.
  24. ; 80   long *lft;// the array to `modify' for left-changes
  25. ; 84   long *rht;// the array to store the right changes in
  26. ; 88   long mod; // the amount to add to go to the next row
  27. ;
  28. ;   All pointers must be long-word aligned for reasonable speed.
  29. ;
  30. ;   This is our main and only entry point.
  31. ;
  32. _dogen:
  33.     movem.l    d1-d7/a0-a6,-(sp)
  34. ;
  35. ;   Our first order of business is to take our `modified' array and `grow' it
  36. ;   by one pixel in each direction.  This is because a change in a cell can
  37. ;   affect each closest neighbor, so we have to recompute them as well.
  38. ;
  39. ;   There are two steps to this.  First, we grow horizontally (a few shifts and
  40. ;   an `or') and then we compute vertically.
  41. ;
  42.     move.l    #128,d0
  43.     sub.w    68(a7),d0
  44.     lsr.w    #2,d0
  45.     move.l    #1,d4
  46.     lsl.l    d0,d4
  47.     neg.l    d4
  48.     move.l    72(a7),a0
  49.     move.l    #0,d1
  50.     move.w    70(a7),d1
  51.     lsl.l    #2,d1
  52.     move.l    #0,d2
  53.     move.l    d2,-4(a0,d1.l)
  54.     move.l    d2,(a0,d1.l)
  55.     move.l    d2,(a0)+
  56.     move.w    70(a7),d1
  57.     sub.w    #2,d1
  58.     bra    orvb
  59. orvl:
  60.     move.l    (a0),d0
  61.     or.l    d0,d2
  62.     or.l    4(a0),d2
  63.     and.l    d4,d2
  64.     move.l    d2,(a0)+
  65.     move.l    d0,d2
  66. orvb:
  67.     dbra    d1,orvl
  68. ;
  69. ;   Now our growing is finished.  We initialize things for our outer loop, which
  70. ;   runs down the scan lines.  Our register usage for the outer loop is as
  71. ;   follows:
  72. ;
  73. ;      a0:  pointer to m array
  74. ;      a1:  pointer to source
  75. ;      a2:  pointer to destination
  76. ;      a3, a4, a5:  pointer to rotating portions of t array
  77. ;      d5:  remaining amount to compute
  78. ;      a6:  row increment (amount to add to go to next row)
  79. ;
  80. ;   We initialize things to point to a fake row before the bitmaps.  This is
  81. ;   necessary because we need to compute the horizontal sums early.  We won't
  82. ;   ever write to these areas, because the modified bits will always be zero
  83. ;   (if the user has made sure that *(m-1) is always zero.)
  84. ;
  85.     move.l    88(a7),d5
  86.     move.l    d5,d0
  87.     add.l    d0,d0
  88.     move.l    d5,a6
  89.     move.l    76(a7),a3
  90.     lea    (a3,d0.l),a4
  91.     lea    (a4,d0.l),a5
  92.     move.l    60(a7),a1
  93.     move.l    64(a7),a2
  94.     move.l    72(a7),a0
  95.     sub.w    #4,a0
  96.     sub.w    d5,a1
  97.     sub.w    d5,a2
  98.     move.w    70(a7),d1
  99.     bra    outb
  100. ;
  101. ;   This is the part of our outer loop that computes the horizontal sums.
  102. ;   We need to compute a horizontal sum if any of the following three rows
  103. ;   needs recomputing.  We only actually do the work if necessary.
  104. ;
  105. ;   If we don't need to compute these, we also don't need to compute the
  106. ;   actual row itself, so we skip past everything.  Pretty cool, eh?
  107. ;
  108. outm:
  109.     move.l    (a0),d7
  110.     or.l    4(a0),d7
  111.     or.l    8(a0),d7
  112.     beq    skippastall
  113.     movem.l    d1/a1/a2,-(sp)
  114.     lea    (a1,a6.w),a1
  115.     move.l    a3,a2
  116. agh:
  117.     add.l    d7,d7
  118.     bcc    skipi
  119. aghi:
  120.     move.l    (a1)+,d0
  121.     move.l    d0,d1
  122.     move.l    d0,d2
  123.     move.b    -5(a1),d3
  124.     lsr.b    #1,d3
  125.     roxr.l    #1,d2
  126.     move.b    (a1),d3
  127.     add.b    d3,d3
  128.     addx.l    d1,d1
  129.     move.l    d1,d3
  130.     and.l    d2,d3
  131.     eor.l    d2,d1
  132.     move.l    d0,d2
  133.     and.l    d1,d2
  134.     eor.l    d0,d1
  135.     or.l    d2,d3
  136.     move.l    d1,(a2)+
  137.     move.l    d3,(a2)+
  138.     add.l    d7,d7
  139.     bcs    aghi
  140. skipone:
  141.     beq    agx
  142. skipi:
  143.     add.w    #4,a1
  144.     add.w    #8,a2
  145.     add.l    d7,d7
  146.     bcs    aghi
  147.     bne    skipi
  148. agx:
  149.     movem.l    (sp)+,d1/a1/a2
  150. ;
  151. ;   Okay, with that out of the way we can compute the new values.  As we compute
  152. ;   the new values, we compare our results with the old results.  If the old
  153. ;   results are different, we set a modified bit in our new array.  Clever, eh?
  154. ;
  155.     move.l    (a0),d7
  156.     beq    skippastall
  157.     movem.l    d1/a1-a5,-(sp)
  158.     move.w    #32,d6
  159.     move.l    #0,d5
  160.     move.l    #0,(a0)
  161. mal:
  162.     sub.w    #1,d6
  163.     add.l    d7,d7
  164.     bcc    skipon3
  165. mal2:
  166.     move.l    (a3)+,d0
  167.     move.l    d0,d1
  168.     move.l    (a4)+,d2
  169.     eor.l    d2,d0
  170.     and.l    d2,d1
  171.     move.l    (a5)+,d2
  172.     move.l    d2,d3
  173.     and.l    d0,d3
  174.     eor.l    d2,d0
  175.     or.l    d3,d1
  176.     move.l    (a3)+,d2
  177.     move.l    d2,d3
  178.     and.l    d1,d2
  179.     eor.l    d3,d1
  180.     move.l    (a4)+,d3
  181.     move.l    d3,d4
  182.     and.l    d1,d3
  183.     eor.l    d4,d1
  184.     eor.l    d3,d2
  185.     move.l    (a5)+,d3
  186.     move.l    d3,d4
  187.     and.l    d1,d3
  188.     eor.l    d4,d1
  189.     eor.l    d3,d2
  190.     not.l    d0
  191.     eor.l    d1,d0
  192.     eor.l    d1,d2
  193.     or.l    (a1)+,d1
  194.     and.l    d1,d0
  195.     and.l    d2,d0
  196.     move.l    (a2)+,d2
  197.     eor.l    d0,d2
  198.     beq    mal
  199.     bpl    sk3
  200.     sub.w    #31,d6
  201.     bcs    sk9
  202.     move.l    104(a7),d1
  203.     sub.l    96(a7),d1
  204.     or.b    #1,3(a0,d1.l)
  205.     bra    sk5
  206. sk9:
  207.     bset    d6,d5
  208. sk5:
  209.     add.w    #31,d6
  210. sk3:
  211.     bset    d6,d5
  212.     lsr.b    #1,d2
  213.     bcc    sk4
  214.     sub.w    #1,d6
  215.     bcc    sk7
  216.     exg    d1,a0
  217.     move.l    108(a7),a0
  218.     move.l    d1,(a0)+
  219.     move.l    a0,108(a7)
  220.     exg    d1,a0
  221.     bra    sk8
  222. sk7:
  223.     bset    d6,d5
  224. sk8:
  225.     add.w    #1,d6
  226. sk4:
  227.     move.l    d0,-4(a2)
  228.     sub.w    #1,d6
  229.     add.l    d7,d7
  230.     bcs    mal2
  231.     beq    max
  232. skipon3:
  233.     add.w    #8,a3
  234.     add.w    #8,a4
  235.     add.w    #8,a5
  236.     add.w    #4,a1
  237.     add.w    #4,a2
  238.     sub.w    #1,d6
  239.     add.l    d7,d7
  240.     bcs    mal2
  241.     bne    skipon3
  242. max:
  243.     move.l    d5,(a0)
  244.     movem.l    (sp)+,d1/a1-a5
  245. skippastall:
  246.     lea    (a1,a6.w),a1
  247.     lea    (a2,a6.w),a2
  248.     add.w    #4,a0
  249.     exg    a3,a4
  250.     exg    a4,a5
  251. outb:
  252.     dbra    d1,outm
  253. fini:
  254.     move.l    84(a7),a0
  255.     move.l    #0,(a0)
  256.     movem.l    (sp)+,d1-d7/a0-a6
  257.     move.l    #0,d0
  258.     rts
  259.